package ypmits.bitmap.pixeldust {
	import ypmits.bitmap.vo.ParticleDataVO;
	import ypmits.utils.SimpleMath;

	import com.greensock.TweenLite;
	import com.greensock.easing.Cubic;

	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.PixelSnapping;
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;

	/**
	 * @author Dave Lenz
	 */
	public class BitmapPixelDust extends Sprite {
		/**
		 * This contains the particles
		 */
		public var particles : Array;
		public var sstage : Stage;
		private var rect : Rectangle = new Rectangle();
		private var bitmap : Bitmap;
		private var pixelsize : int;
		private var explosionpoint : Point;
		private var radius : int = 15;
		private var done : int = 0;

		public function BitmapPixelDust( pixelsize : int = 1, bitmap : Bitmap = null )
		{
			this.pixelsize = pixelsize;
			this.bitmap = bitmap;

			if( bitmap ) {
				x = bitmap.x;
				y = bitmap.y;
				makeDustFromBitmap( bitmap, true, true );
			}
			
			alpha = 0;
			visible = false;
		}


		public function start() : void
		{
			sstage.addEventListener( MouseEvent.MOUSE_MOVE, mHandler );
		}


		public function stop() : void
		{
			sstage.removeEventListener( MouseEvent.MOUSE_MOVE, mHandler );
		}


		public function startAnim( time : Number = 2, delay : Number = 0, ease : Object = null ) : void
		{
			!ease ? ease = Cubic.easeOut : null;

			TweenLite.to( this, .3, {autoAlpha:1, ease:Cubic.easeInOut} );

			var obj : DisplayObject;
			var tx : Number;
			var ty : Number;
			for (var i : int = 0; i < particles.length; i++) {
				obj = BitmapPixelDustParticle( particles[i] ).particledata.obj;
				tx = BitmapPixelDustParticle( particles[i] ).particledata.x;
				ty = BitmapPixelDustParticle( particles[i] ).particledata.y;
				obj.x = SimpleMath.getRandomNumberBetween( tx - 600, tx + 600 );
				obj.y = SimpleMath.getRandomNumberBetween( ty - 400, ty + 400 );

				obj.alpha = 0;

				TweenLite.to( obj, time, { x:tx, y:ty, alpha:1, delay:(i * .001) + delay, ease:ease, onComplete:startAnimDone } );
			}
		}


		private function startAnimDone() : void
		{
			if( ++done == particles.length ) {
				dispatchEvent( new Event( Event.COMPLETE ) );
			}
		}


		private function mHandler( e : MouseEvent ) : void
		{
			var particle : BitmapPixelDustParticle;
			var obj : DisplayObject;

			rect.x = mouseX - radius;
			rect.y = mouseY - radius;
			rect.width = radius * 2;
			rect.height = radius * 2;

			graphics.clear();
			graphics.beginFill( 0xFF9900, 0 );
			graphics.drawCircle( rect.x, rect.y, radius );

			if( e.type == MouseEvent.MOUSE_MOVE ) {
				for (var i : int = 0; i < particles.length; i++) {
					particle = BitmapPixelDustParticle( particles[i] );
					obj = particle.particledata.obj;
					if( rect.containsPoint( new Point( obj.x, obj.y ) ) ) {
						particle.render( new Point( mouseX, mouseY ), radius );
					}
				}
			}
		}


		public function startExplode( explosionpoint : Point ) : void
		{
			this.explosionpoint = explosionpoint;
			radius = 15;
			addEventListener( Event.ENTER_FRAME, explodeHandler );
		}


		public function stopExplode() : void
		{
			removeEventListener( Event.ENTER_FRAME, explodeHandler );
		}


		private function explodeHandler( event : Event ) : void
		{
			var particle : BitmapPixelDustParticle;
			var obj : DisplayObject;

			for (var i : int = 0; i < particles.length; i++) {
				particle = BitmapPixelDustParticle( particles[i] );
				obj = particle.particledata.obj;

				particle.render( new Point( 50, 50 ), radius );
				radius += .1;
			}
		}


		public function makeDustFromBitmap( bitmap : Bitmap, autodraw : Boolean = true, alphazero : Boolean = false ) : void
		{
			particles = [];
			var bmd : BitmapData = bitmap.bitmapData;
			var w : int = bmd.width;
			var h : int = bmd.height;
			bmd.lock();
			for( var i : int = 0; i < w ; i += pixelsize ) {
				for( var j : int = 0; j < h ; j += pixelsize ) {
					if( bmd.getPixel( i, j ) > 0 ) {
						var p : Bitmap = new Bitmap( new BitmapData( pixelsize, pixelsize, true, 0x00FF9900 ), PixelSnapping.NEVER, true );
						p.bitmapData.copyPixels( bmd, new Rectangle( i, j, pixelsize, pixelsize ), new Point( 0, 0 ) );
						p.x = i;
						p.y = j;
						alphazero ? p.alpha = 0 : null;

						var particle : BitmapPixelDustParticle = new BitmapPixelDustParticle( new ParticleDataVO( i, j, p ) );
						particles.push( particle );
						autodraw ? addChild( particle ) : null;
						
					}
				}
			}
			bmd.unlock();
		}
	}
}
